package com.googlecode.bip.xml.importe;

import java.sql.SQLException;
import java.util.ArrayDeque;
import java.util.Deque;
import javax.naming.NamingException;
import org.apache.log4j.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import com.googlecode.bip.entity.IllegalIdLocalException;
import com.googlecode.bip.entity.IllegalValueException;

/**
 *
 * @author Claude CHOISNET
 */
//no public
class SurveyScanner
{
    private static final Logger logger = Logger.getLogger( SurveyScanner.class );
    private final Deque<SQLTopic> storeTopicsQueue = new ArrayDeque<SQLTopic>();
    private final Deque<SQLTopicLocal> storeTopicsLocalQueue = new ArrayDeque<SQLTopicLocal>();
    private final Deque<SQLQuestion> storeQuestionsQueue = new ArrayDeque<SQLQuestion>();
    private final Deque<SQLQuestionLocal> storeQuestionsLocalQueue = new ArrayDeque<SQLQuestionLocal>();
    private final Deque<SQLValueDescription> storeValueDescriptionQueue = new ArrayDeque<SQLValueDescription>();
    private final SQLStatementCollection sqlCollection;

    private void doSurvey(final SQLStatementCollection sqlCollection)
    {
        // TO DO ???
        // logger.info( "--- doSurvey() ------------" );
    }
    private void doneSurvey()
    {
        if( storeTopicsQueue.size() > 0 ) {
            throw new RuntimeException("storeTopicsQueue not empty");
            }
        if( storeTopicsLocalQueue.size() > 0 ) {
            throw new RuntimeException("storeTopicsLocalQueue not empty");
            }
        if( storeQuestionsQueue.size() > 0 ) {
            throw new RuntimeException("storeQuestionsQueue not empty");
            }
        if( storeQuestionsLocalQueue.size() > 0 ) {
            throw new RuntimeException("storeQuestionsLocalQueue not empty");
            }
        if( storeValueDescriptionQueue.size() > 0 ) {
            throw new RuntimeException("storeValueDescriptionQueue not empty");
            }
        logger.info( "--- doneWithSurvey() ------------" );
    }


    private static Element findChildNode( Element element, String name )
    {
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            if( node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE ) {
                org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
                if( nodeElement.getTagName().equals("idtopic" ) ) {
                    return nodeElement;
                    }
                }
            }
        return null;
    }

    private static String findChildText( Element element/*, String name*/ )
    {
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            if( node.getNodeType() == org.w3c.dom.Node.TEXT_NODE ) {
                return ((org.w3c.dom.Text)node).getData();
                }
            }
        return null;
    }

    private void doTopic(Element element)
    {
        storeTopicsQueue.addFirst( new SQLTopic( sqlCollection ) );

        if( logger.isDebugEnabled() ) {
            logger.debug( "### doTopic(): " + element );
            //logger.debug( "### " + element.lookupPrefix( "idtopic" ) );
            //logger.debug( "### getNodeValue " + element.getNodeValue() );
            logger.debug( "### getChildNodes " + element.getChildNodes() );
            //logger.debug( "### getChildNodes " + element.getChildNodes().getLength() );
            logger.debug( "### findChildNode " + findChildNode( element, "idtopic" ) );
            }
        Element itNode = findChildNode( element, "idtopic" );

        if( logger.isDebugEnabled() ) {
            logger.debug( "### findChildText " + findChildText( itNode ) );
            }
        //((org.w3c.dom.Text)(element.getChildNodes().item(6).getChildNodes().item(0))).getData()
    }

    private void storeTopic(
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            )
    {
        SQLTopic thisSQLTopic = storeTopicsQueue.peek();

        if( logger.isDebugEnabled() ) {
            debugStore( "* storeTopic (" + thisSQLTopic + ")", nodeElement, node );
            }

        if( "topic".equals( nodeElement.getParentNode().getNodeName() ) ) {

            if( "idtopic".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLTopic.setIdTopic( Integer.parseInt(value));
                }
            else if( "order".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLTopic.setOrder( Integer.parseInt(value));
                }
            else if( "isactive".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLTopic.setIsActive( Integer.parseInt(value));
                }
            else {
                throw newIllegalNodeNameException(nodeElement,node);
                }
            }
        else {
            //_store( "**** storeTopic (" + storeTopicsMap.size() + ")", nodeElement, node );
            throw newIllegalParentNodeNameException("topic", nodeElement,node);
            }
    }
    private void doneTopic(org.w3c.dom.Element nodeElement)
        throws NamingException, SQLException, IllegalValueException
    {
        SQLTopic sqlTopic = storeTopicsQueue.pop();

        if( logger.isDebugEnabled() ) {
            logger.debug( "<<< doneWithTopic(): " + sqlTopic );
            logger.debug( "<<< doneWithTopic() queue size=" + storeTopicsQueue.size() );
            }

        if( "topic".equals( nodeElement.getParentNode().getNodeName() ) ) {
            storeTopicsQueue.peek().add( sqlTopic );
            }
        else if( "survey".equals( nodeElement.getParentNode().getNodeName() ) ) {
            sqlTopic.commit();
            }
        else {
            throw new IllegalStateException( "unexpected: " + nodeElement.getParentNode().getNodeName() );
            }
    }

    private void doTopicLocal()
    {
        //logger.info( "--- doTopicLocal() ------------" );
        storeTopicsLocalQueue.addFirst( new SQLTopicLocal( sqlCollection ) );
    }
    private void storeTopicLocal(
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            )
    {
        SQLTopicLocal thisSQLTopicLocal = storeTopicsLocalQueue.peek();

       //debug( "storeTopicLocal", nodeElement, node );

        if( "topiclocal".equals( nodeElement.getParentNode().getNodeName() ) ) {
            if( "local".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLTopicLocal.setIdLocal( value );
                }
            else if( "topicname".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLTopicLocal.setTopicName(value);
                }
            else if( "topicdescription".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLTopicLocal.setTopicDescription(value);
                }
            else {
                throw newIllegalNodeNameException(nodeElement,node);
                }
            }
        else {
            throw newIllegalParentNodeNameException("topiclocal", nodeElement,node);
            }
    }
    private void doneTopicLocal()
    {
        storeTopicsQueue.peek().add( storeTopicsLocalQueue.pop() );

        if( logger.isDebugEnabled() ) {
            logger.debug( "--- doneWithTopicLocal() ------------" );
            }
    }

    private void doQuestion()
    {
        //logger.debug( "--- doQuestion() ------------" );
        storeQuestionsQueue.addFirst( new SQLQuestion( sqlCollection ) );
    }
    private void storeQuestion(
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            )
    {
        SQLQuestion thisSQLQuestion = storeQuestionsQueue.peek();

        if( "question".equals( nodeElement.getParentNode().getNodeName() ) ) {
            if( "idquestion".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestion.setIdQuestion( Integer.parseInt( value ) );
                }
            else if( "order".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestion.setOrder( Integer.parseInt( value ) );
                }
            else if( "isactive".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestion.setIsActive( Integer.parseInt( value ) );
                }
            else if( "minvalue".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestion.setMinValue( Integer.parseInt( value ) );
                }
            else if( "maxvalue".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestion.setMaxValue( Integer.parseInt( value ) );
                }
            else if( "defaultvalue".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestion.setDefaultValue( Integer.parseInt( value ) );
                }
            else {
                throw newIllegalNodeNameException(nodeElement,node);
                }
            }
        else {
            throw newIllegalParentNodeNameException("question", nodeElement,node);
            }
        //_store( "storeQuestion", nodeElement, node );
    }

    private void doneQuestion(org.w3c.dom.Element nodeElement)
        throws NamingException, SQLException, IllegalValueException
    {
        SQLQuestion sqlQuestion = storeQuestionsQueue.pop();

        if( logger.isDebugEnabled() ) {
            logger.debug( "<<< doneWithTopic(): " + sqlQuestion );
            }

        if( "topic".equals( nodeElement.getParentNode().getNodeName() ) ) {
            storeTopicsQueue.peek().add( sqlQuestion );
            }
        else if( "survey".equals( nodeElement.getParentNode().getNodeName() ) ) {
            sqlQuestion.commit();
            }
        else {
            throw new IllegalStateException( "unexpected: " + nodeElement.getParentNode().getNodeName() );
            }
        if( logger.isDebugEnabled() ) {
            logger.debug( "<<< doneWithQuestion() - queue size=" + storeTopicsQueue.size() );
            }
    }

    private void doQuestionLocal()
    {
        //logger.debug( "--- doQuestionLocal() ------------" );
        storeQuestionsLocalQueue.addFirst( new SQLQuestionLocal( sqlCollection ) );
    }
    private void storeQuestionLocal(
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            ) throws IllegalIdLocalException
    {
        SQLQuestionLocal thisSQLQuestionLocal = storeQuestionsLocalQueue.peek();

        if( "questionlocal".equals( nodeElement.getParentNode().getNodeName() ) ) {
            if( "local".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestionLocal.setIdLocal( value );
                }
            else if( "questionname".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestionLocal.setQuestionName(value);
                }
            else if( "questiondescription".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLQuestionLocal.setQuestionDescription(value);
                }
            else {
                throw newIllegalNodeNameException(nodeElement,node);
                }
            }
        else {
            throw newIllegalParentNodeNameException("questionlocal", nodeElement,node);
            }
        //_store( "storeQuestionLocal", nodeElement, node );
    }

    private void doneQuestionLocal()
    {
        storeQuestionsQueue.peek().add( storeQuestionsLocalQueue.pop() );

        if( logger.isDebugEnabled() ) {
            logger.debug( "--- doneWithQuestionLocal() ------------" );
            }
    }

    private void doValueDescriptions()
    {
        //logger.debug( "--- doValueDescriptions() ------------" );
        storeValueDescriptionQueue.addFirst( new SQLValueDescription( sqlCollection ) );
    }

    private void storeValueDescriptions(
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            )
    {
        SQLValueDescription thisSQLValueDescription = storeValueDescriptionQueue.peek();

        if( "valuedescriptions".equals( nodeElement.getParentNode().getNodeName() ) ) {
            if( "value".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLValueDescription.setValue( Integer.parseInt( value ) );
                }
            else if( "valuedescription".equals( nodeElement.getTagName() ) ) {
                String value = node.getData();
                thisSQLValueDescription.setValueDescription(value);
                }

            else {
                throw newIllegalNodeNameException(nodeElement,node);
                }
            }
        else {
            throw newIllegalParentNodeNameException("questionlocal", nodeElement,node);
            }
        //_store( "storeDescriptions", nodeElement, node );
    }
    private void doneValueDescriptions()
    {
        storeQuestionsLocalQueue.peek().add( storeValueDescriptionQueue.pop() );
        //logger.debug( "--- doneWithValueDescriptions() ------------" );
    }

    private void storeXLocal(
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            ) throws IllegalIdLocalException
    {
        if( nodeElement.getParentNode().getNodeName().equals( "questionlocal" )) {
            storeQuestionLocal( nodeElement, node );
            }
        else if( nodeElement.getParentNode().getNodeName().equals( "topiclocal" )) {
            storeTopicLocal( nodeElement, node );
            }
        else {
            throw new IllegalStateException( "nodename: " + nodeElement.getParentNode().getNodeName() );
            }
    }

    private void storeXOrder(Element nodeElement, Text node)
    {
        if( nodeElement.getParentNode().getNodeName().equals( "question" )) {
            storeQuestion( nodeElement, node );
            }
        else if( nodeElement.getParentNode().getNodeName().equals( "topic" )) {
            storeTopic( nodeElement, node );
            }
        else {
            throw new IllegalStateException( "nodename: " + nodeElement.getParentNode().getNodeName() );
            }
    }

    private void storeXIsActive(Element nodeElement, Text node)
    {
        if( nodeElement.getParentNode().getNodeName().equals( "question" )) {
            storeQuestion( nodeElement, node );
            }
        else if( nodeElement.getParentNode().getNodeName().equals( "topic" )) {
            storeTopic( nodeElement, node );
            }
        else {
            throw new IllegalStateException( "nodename: " + nodeElement.getParentNode().getNodeName() );
            }
    }

    private void storeXIdTopic( Element nodeElement, Text node )
    {
        if( nodeElement.getParentNode().getNodeName().equals( "question" )) {
            storeQuestion( nodeElement, node );
            }
        else {
            storeTopic( nodeElement, node );
            }
    }

    private void debugStore(
            String message,
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            )
    {
        logger.debug(
            "["
                + message
                + "] parent"
                + nodeElement.getParentNode()
                + " * `"
                + nodeElement.getTagName()
                + "`='"
                + node.getData()
                + "'"
            );
    }

    /**
     * org.w3c.dom.Document document
     */
    org.w3c.dom.Document document;

    /**
     * Create new SurveyScanner with org.w3c.dom.Document.
     */
    public SurveyScanner(
            final SQLStatementCollection         sqlCollection,
            final org.w3c.dom.Document  document
            )
    {
        this.document       = document;
        this.sqlCollection  = sqlCollection;
    }

    /**
     * Scan through org.w3c.dom.Document document.
     * @throws SQLException
     * @throws NamingException
     * @throws IllegalIdLocalException 
     * @throws IllegalValueException 
     */
    public void visitDocument() throws NamingException, SQLException, IllegalIdLocalException, IllegalValueException
    {
        org.w3c.dom.Element element = document.getDocumentElement();
        if ((element != null) && element.getTagName().equals("survey")) {
            visitElement_survey(element);
        }
        else if ((element != null) && element.getTagName().equals("topic")) {
            visitElement_topic(element);
        }
        else if ((element != null) && element.getTagName().equals("idtopic")) {
            visitElement_idtopic(element);
        }
        else if ((element != null) && element.getTagName().equals("order")) {
            visitElement_order(element);
        }
        else if ((element != null) && element.getTagName().equals("isactive")) {
            visitElement_isactive(element);
        }
        else if ((element != null) && element.getTagName().equals("topiclocal")) {
            visitElement_topiclocal(element);
        }
        else if ((element != null) && element.getTagName().equals("local")) {
            visitElement_local(element);
        }
        else if ((element != null) && element.getTagName().equals("topicname")) {
            visitElement_topicname(element);
        }
        else if ((element != null) && element.getTagName().equals("topicdescription")) {
            visitElement_topicdescription(element);
        }
        else if ((element != null) && element.getTagName().equals("question")) {
            visitElement_question(element);
        }
        else if ((element != null) && element.getTagName().equals("idquestion")) {
            visitElement_idquestion(element);
        }
        else if ((element != null) && element.getTagName().equals("minvalue")) {
            visitElement_minvalue(element);
        }
        else if ((element != null) && element.getTagName().equals("maxvalue")) {
            visitElement_maxvalue(element);
        }
        else if ((element != null) && element.getTagName().equals("defaultvalue")) {
            visitElement_defaultvalue(element);
        }
        else if ((element != null) && element.getTagName().equals("questionlocal")) {
            visitElement_questionlocal(element);
        }
        else if ((element != null) && element.getTagName().equals("questionname")) {
            visitElement_questionname(element);
        }
        else if ((element != null) && element.getTagName().equals("questiondescription")) {
            visitElement_questiondescription(element);
        }
        else if ((element != null) && element.getTagName().equals("valuedescriptions")) {
            visitElement_valuedescriptions(element);
        }
        else if ((element != null) && element.getTagName().equals("value")) {
            visitElement_value(element);
        }
        else if ((element != null) && element.getTagName().equals("valuedescription")) {
            visitElement_valuedescription(element);
        }
    }

    /**
     * Scan through org.w3c.dom.Element named survey.
     * @throws SQLException
     * @throws NamingException
     * @throws IllegalIdLocalException 
     * @throws IllegalValueException 
     */
    void visitElement_survey(org.w3c.dom.Element element)
        throws NamingException, SQLException, IllegalIdLocalException, IllegalValueException
    {
        // <survey>
        // element.getValue();
        doSurvey( sqlCollection );
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
                    if (nodeElement.getTagName().equals("topic")) {
                        visitElement_topic(nodeElement);
                    }
                    if (nodeElement.getTagName().equals("question")) {
                        visitElement_question(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
        doneSurvey();
    }

    /**
     * Scan through org.w3c.dom.Element named topic.
     * @throws SQLException
     * @throws NamingException
     * @throws IllegalIdLocalException 
     * @throws IllegalValueException 
     */
    void visitElement_topic(org.w3c.dom.Element element)
        throws NamingException, SQLException, IllegalIdLocalException, IllegalValueException
    {
        // <topic>
        // element.getValue();
        doTopic( element );
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
                    if (nodeElement.getTagName().equals("topic")) {
                        visitElement_topic(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("idtopic")) {
                        visitElement_idtopic(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("order")) {
                        visitElement_order(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("isactive")) {
                        visitElement_isactive(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("topiclocal")) {
                        visitElement_topiclocal(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("question")) {
                        visitElement_question(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
        doneTopic(element);
    }

    /**
     * Scan through org.w3c.dom.Element named idtopic.
     */
    void visitElement_idtopic(org.w3c.dom.Element element) {
        // <idtopic>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeXIdTopic(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named order.
     */
    void visitElement_order(org.w3c.dom.Element element) {
        // <order>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeXOrder(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named isactive.
     */
    void visitElement_isactive(org.w3c.dom.Element element) {
        // <isactive>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeXIsActive(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named topiclocal.
     * @throws IllegalIdLocalException 
     */
    void visitElement_topiclocal(org.w3c.dom.Element element) throws IllegalIdLocalException {
        // <topiclocal>
        // element.getValue();
        doTopicLocal();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
                    if (nodeElement.getTagName().equals("local")) {
                        visitElement_local(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("topicname")) {
                        visitElement_topicname(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("topicdescription")) {
                        visitElement_topicdescription(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
        doneTopicLocal();
    }


    /**
     * Scan through org.w3c.dom.Element named local.
     * @throws IllegalIdLocalException 
     */
    void visitElement_local(org.w3c.dom.Element element) throws IllegalIdLocalException {
        // <local>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeXLocal(element, (org.w3c.dom.Text)node );
                    //storeTopicLocal(element, (org.w3c.dom.Text)node );
                   // storeQuestionLocal(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named topicname.
     */
    void visitElement_topicname(org.w3c.dom.Element element) {
        // <topicname>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeTopicLocal(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named topicdescription.
     */
    void visitElement_topicdescription(org.w3c.dom.Element element) {
        // <topicdescription>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeTopicLocal(element, (org.w3c.dom.Text)node );
                    break;
            }
        }

    }

    /**
     * Scan through org.w3c.dom.Element named question.
     * @throws SQLException
     * @throws NamingException
     * @throws IllegalIdLocalException 
     * @throws IllegalValueException 
     */
    void visitElement_question(org.w3c.dom.Element element)
        throws NamingException, SQLException, IllegalIdLocalException, IllegalValueException
    {
        // <question>
        // element.getValue();
        doQuestion();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
                    if (nodeElement.getTagName().equals("order")) {
                        visitElement_order(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("isactive")) {
                        visitElement_isactive(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("idquestion")) {
                        visitElement_idquestion(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("minvalue")) {
                        visitElement_minvalue(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("maxvalue")) {
                        visitElement_maxvalue(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("defaultvalue")) {
                        visitElement_defaultvalue(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("questionlocal")) {
                        visitElement_questionlocal(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
        doneQuestion(element);
    }


    /**
     * Scan through org.w3c.dom.Element named idquestion.
     */
    void visitElement_idquestion(org.w3c.dom.Element element) {
        // <idquestion>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeQuestion(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named minvalue.
     */
    void visitElement_minvalue(org.w3c.dom.Element element) {
        // <minvalue>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeQuestion(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named maxvalue.
     */
    void visitElement_maxvalue(org.w3c.dom.Element element) {
        // <maxvalue>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeQuestion(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named defaultvalue.
     */
    void visitElement_defaultvalue(org.w3c.dom.Element element) {
        // <defaultvalue>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeQuestion(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named questionlocal.
     * @throws IllegalIdLocalException 
     */
    void visitElement_questionlocal(org.w3c.dom.Element element) throws IllegalIdLocalException {
        // <questionlocal>
        // element.getValue();
        doQuestionLocal();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
                    if (nodeElement.getTagName().equals("local")) {
                        visitElement_local(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("questionname")) {
                        visitElement_questionname(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("questiondescription")) {
                        visitElement_questiondescription(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("valuedescriptions")) {
                        visitElement_valuedescriptions(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
        doneQuestionLocal();
    }


    /**
     * Scan through org.w3c.dom.Element named questionname.
     * @throws IllegalIdLocalException 
     */
    void visitElement_questionname(org.w3c.dom.Element element) throws IllegalIdLocalException {
        // <questionname>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeQuestionLocal(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named questiondescription.
     * @throws IllegalIdLocalException 
     */
    void visitElement_questiondescription(org.w3c.dom.Element element) throws IllegalIdLocalException {
        // <questiondescription>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeQuestionLocal(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named valuedescriptions.
     */
    void visitElement_valuedescriptions(org.w3c.dom.Element element) {
        // <valuedescriptions>
        // element.getValue();
        doValueDescriptions();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
                    if (nodeElement.getTagName().equals("value")) {
                        visitElement_value(nodeElement);
                    }
                    else if (nodeElement.getTagName().equals("valuedescription")) {
                        visitElement_valuedescription(nodeElement);
                    }
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
            }
        }
        doneValueDescriptions();
    }

    /**
     * Scan through org.w3c.dom.Element named value.
     */
    void visitElement_value(org.w3c.dom.Element element) {
        // <value>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeValueDescriptions(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    /**
     * Scan through org.w3c.dom.Element named valuedescription.
     */
    void visitElement_valuedescription(org.w3c.dom.Element element) {
        // <valuedescription>
        // element.getValue();
        org.w3c.dom.NodeList nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            org.w3c.dom.Node node = nodes.item(i);
            switch (node.getNodeType()) {
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                    // ((org.w3c.dom.CDATASection)node).getData();
                    break;
                case org.w3c.dom.Node.ELEMENT_NODE:
//                    org.w3c.dom.Element nodeElement = (org.w3c.dom.Element) node;
//                    display(nodeElement);
                    break;
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    // ((org.w3c.dom.ProcessingInstruction)node).getTarget();
                    // ((org.w3c.dom.ProcessingInstruction)node).getData();
                    break;
                case org.w3c.dom.Node.TEXT_NODE:
                    // ((org.w3c.dom.Text)node).getData();
                    storeValueDescriptions(element, (org.w3c.dom.Text)node );
                    break;
            }
        }
    }

    private IllegalStateException newIllegalParentNodeNameException(
            String              expectedParentNodeName,
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            )
    {
        return new IllegalStateException(
            "IllegalParentNodeName - nodename: " + nodeElement.getTagName()
            + " parent: " + nodeElement.getParentNode()
              + " EXPECTED: " + expectedParentNodeName
            + " `"
            + node.getData()
            + "'"
            );
    }

    private IllegalStateException newIllegalNodeNameException(
            org.w3c.dom.Element nodeElement,
            org.w3c.dom.Text    node
            )
    {
        return new IllegalStateException(
            "IllegalNodeName - nodename: " + nodeElement.getTagName()
            + " parent: " + nodeElement.getParentNode()
            + " `"
            + node.getData()
            + "'"
            );
    }

}
